package amst.system;
/**
 *
 * @author maya
 */
public class CWTPScheduler implements Scheduler
{
    private double [][] matrix;
    private int[] rowPrefer =  {0, 0, 0};
    private int[] columnPrefer = {0, 0, 0};
    private int[] sumBoth = {0, 0, 0};
	private int[] ddps = new int[3];
	
	public int findNextQueue(SystemQueue queues[], double actualTime)
    {   
        int queue_number = -1;
        double max = -10000;
        
        
        this.matrix = countQueuesWTP(queues);
/*
        System.out.println("MATRIX: ");
        for (int i = 0; i < 3; i++)
        {
        for (int j = 0; j < 3; j++) System.out.print(matrix[i][j] + " ");
        System.out.println();
        }
*/
        this.countVectors();
        for (int i = 0; i < 3; i++)
        {
            if (sumBoth[i] >= max)
            { 
                max = sumBoth[i];
                queue_number = i;
            }
        }
/*
        System.out.println("Next_queue: " + queue_number + " " +
                           "ColumnPrefer: " + columnPrefer[0] + " " + columnPrefer[1] + " " + columnPrefer[2] + " " +
                           "RowPrefer: " + rowPrefer[0] + " " + rowPrefer[1] + " " + rowPrefer[2] + " " +
                           "SumBoth: " + sumBoth[0] + " " + sumBoth[1] + " " + sumBoth[2] + " " +
                           "DDP: " + DDP[0] + " " + DDP[1] + " " + DDP[2]);
*/
        if(queues[queue_number].checkPacket() != null)
        System.out.println("systime: " + queues[0].getPacketSystem().getPSTime() + "  " +
                           "service_time: " + queues[queue_number].checkPacket().getServiceTime() + "\t" +
                           "queue_number: " + queue_number + " " +
                           "Queues delays: " + (int)(queues[0].getPacketDelay()/ddps[0]) + "\t" +
                                               (int)(queues[1].getPacketDelay()/ddps[1]) + "\t" +
                                               (int)(queues[2].getPacketDelay()/ddps[2]) + "\t" +
                           "Queues sizes: " +  queues[0].getSize() + " " +
                                               queues[1].getSize() + " " +
                                               queues[2].getSize() + "\t" +
                           "DDPs: " + ddps[0] + " " + ddps[1] + " " + ddps[2]);
        
        return queue_number;
    }
    //Funkcja obliczajaca wektory pomocnicze columnPrefer, rowPrefer, sumBoth
    private void countVectors()
    {   double[][] maxvalues;
        for(int i=0; i<3; i++)
        {   
            rowPrefer[i] = 0;
            columnPrefer[i] = 0;
            sumBoth[i] = 0;    
        }    
        maxvalues = this.findmax(3);
        for (int i = 0; i < 3; i ++)
        {
            rowPrefer[(int)maxvalues[i][1]]--;
            columnPrefer[(int)maxvalues[i][2]]++;
        }
        for(int i = 0; i <3; i++) sumBoth[i] = rowPrefer[i] + columnPrefer[i];
        }
    
    //funkcja zwracajaca n maksymalnych wartosci macierzy 
    //w postaci (wartosc, numer wiersza, numer kolumny)
    private double[][] findmax (int n)
    {   
        double[][] matrixValues, result;
        double[] tmp;
        int i, j, k;
        
        k = 0;
        matrixValues = new double[9][3];
        result = new double[n][3];
        
        for(i = 0; i < 3; i++)
            for(j = 0; j < 3; j++)
            {
                matrixValues[k][0] = matrix[i][j];
                matrixValues[k][1] = i;
                matrixValues[k][2] = j;
                k++;
            }
        for (i = 0; i < k; i++)
            for (j = 0; j < i; j++)
            {
                if (matrixValues[j][0] < matrixValues[i][0])
                {
                    tmp = matrixValues[i];
                    matrixValues[i] = matrixValues[j];
                    matrixValues[j] = tmp;
                }
            }
        for (i=0; i<n; i++) result[i] = matrixValues[i];
       return result;
    }
    //Uwaga! Troche inne zastosowanie drugiego parametru. Obliczamy V[j,i],
    //gdzie i - numer kolejki, z ktorej odczytujemy czas obsługi.
    
    public double countWTP(Packet packet, int i,double actualTime)
    {
		return 0;
	}
    

    public double[][] countQueuesWTP(SystemQueue[] queues)
    {
        double [][] param_matrix = new double [3][3];
        double service_time = 0;
        double delay = 0;
        
        double time = queues[0].getPacketSystem().getPSTime();
        
        for (int i=0; i<3; i++)
        {
            service_time = 0;
            if (queues[i].checkPacket() != null) service_time = queues[i].checkPacket().getServiceTime();
            
            for (int j=0; j<3; j++)
            {   
                delay = 0;
                if (queues[j].checkPacket() != null) delay = queues[j].checkPacket().getDelay(time);
                
                if (i == j) param_matrix[i][j] = delay/ddps[j];
                else        param_matrix[i][j] = (delay + service_time)/ddps[j];
            }
        }
 
        return param_matrix;
    }
    
	public void setDDP(int[] ddps) {
		this.ddps[0] = ddps[0];  
		this.ddps[1] = ddps[1];
		this.ddps[2] = ddps[2];
	}
}
